//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.DataLayer
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections.ObjectModel;
    using System.Linq;

    public partial class Group
    {
        public string ImagePath
        {
            get
            {
                return "/Microsoft.Research.ScientificWorkflow.TridentUtilities;component/Images/ManagementStudio/groups.png";
            }
        }

        # region CommonSearches
        public sealed class CommonSearches
        {
            private const string SYSTEMGROUP = "everyone";

            private CommonSearches()
            {
            }

            /// <summary>
            /// Fetches all the Groups 
            /// </summary>
            /// <param name="connection">Registry connectionection.</param>
            /// <returns>Collection of groups </returns>
            public static List<Group> GetAllGroups(Connection connection)
            {
                #region Validation of Arguments

                if (null == connection)
                {
                    throw new ArgumentNullException("connection");
                }



                #endregion
                List<Group> allGroups = null;
                try
                {
                    Group.ISearch searchQuery = Group.ISearch.Create();
                    searchQuery.Query = Group.ISearch.AND(
                        Group.ISearch.Name(StringField.Condition.NotEquals, SYSTEMGROUP),
                        Group.ISearch.IsDeleted(BooleanField.Condition.Equals, false));
                    allGroups = new List<Group>(Group.Search(searchQuery, connection));
                }
                catch (RecordNotFoundException)
                {
                    allGroups = new List<Group>();
                }
                return allGroups;
            }

            /// <summary>
            /// Fetches all the Active Groups 
            /// </summary>
            /// <param name="connection">Registry connectionection.</param>
            /// <returns>Collection of groups </returns>
            public static List<Group> GetAllActiveGroups(Connection connection)
            {
                #region Validation of Arguments

                if (null == connection)
                {
                    throw new ArgumentNullException("connection");
                }


                #endregion
                List<Group> allGroups = null;
                try
                {
                    Group.ISearch searchQuery = Group.ISearch.Create();
                    searchQuery.Query = Group.ISearch.AND(
                        Group.ISearch.Name(StringField.Condition.NotEquals, SYSTEMGROUP),
                        Group.ISearch.Enabled(BooleanField.Condition.Equals, true),
                        Group.ISearch.IsDeleted(BooleanField.Condition.Equals, false));
                    allGroups = new List<Group>(Group.Search(searchQuery, connection));
                }
                catch (RecordNotFoundException)
                {
                    allGroups = new List<Group>();
                }
                return allGroups;
            }


            /// <summary>
            /// Counts all the active non deleted Groups other than passed Group Id
            /// </summary>
            /// <param name="connection">Registry connectionection.</param>
            /// <param name="id">group Id</param>
            /// <returns>Collection of groups </returns>
            public static int GetAllAdminGroupsCount(Connection connection, Guid id)
            {
                #region Validation of Arguments

                if (null == connection)
                {
                    throw new ArgumentNullException("connection");
                }

                #endregion
                Collection<SystemRole> allAdminRoles = null;
                List<ISecurityPrincipal> adminGroups = new List<ISecurityPrincipal>();

                try
                {
                    SystemRole.ISearch searchQuery = SystemRole.ISearch.Create();
                    searchQuery.Query = SystemRole.ISearch.BuiltinRole(EnumFieldBase.Condition.Equals, SystemBuiltinRoleType.Administrators);
                    allAdminRoles = new Collection<SystemRole>(SystemRole.Search(searchQuery, connection));
                    foreach (SystemRole sys in allAdminRoles)
                    {
                        if (sys.MemberGroupPrincipal != null && sys.MemberGroupPrincipal.Enabled && sys.MemberGroupPrincipal.IsDeleted == false
                            && !sys.MemberGroupPrincipal.Name.Equals(SYSTEMGROUP, StringComparison.OrdinalIgnoreCase)
                            && !((IObject)sys.MemberGroupPrincipal).ID.Equals(id))
                        {
                            adminGroups.Add(sys.MemberGroupPrincipal);
                        }
                    }

                }
                catch (RecordNotFoundException)
                {

                }

                return adminGroups.Count;
            }


            public static bool GroupExistInRegistry(Guid id, string groupName, Connection connection)
            {
                #region Validation of Arguments

                if (null == connection)
                {
                    throw new ArgumentNullException("connection");
                }

                Collection<Group> groups = new Collection<Group>();

                #endregion

                try
                {
                    Group.ISearch searchQuery = Group.ISearch.Create();
                    searchQuery.Query = Group.ISearch.AND(
                        Group.ISearch.Name(StringField.Condition.Equals, groupName),
                        Group.ISearch.IsDeleted(BooleanField.Condition.Equals, false));

                    groups = new Collection<Group>(Group.Search(searchQuery, connection));

                    int count;
                    if (!id.Equals(Guid.Empty))
                    {
                        count = (from p in groups where !((IObject)p).ID.Equals(id) select p).Count();
                    }
                    else
                    {
                        count = (from p in groups select p).Count();
                    }

                    return count > 0;
                    //}
                }
                catch (RecordNotFoundException)
                {
                    groups = null;
                }

                return false;
            }

            /// <summary>
            /// Fetches all active Group other than Passed group Name  
            /// </summary>
            /// <param name="groupName">GroupNames</param>
            /// <param name="connection">Registry connectionection.</param>
            /// <returns>Collection of Group .</returns>
            public static Collection<Group> GetAllGroupsByFilter(string groupName, Connection connection)
            {
                #region Validation of Arguments

                if (null == connection)
                {
                    throw new ArgumentNullException("connection");
                }

                #endregion
                Collection<Group> allGroups = null;
                try
                {
                    Group.ISearch searchQuery = Group.ISearch.Create();
                    searchQuery.Query = Group.ISearch.AND(
                        Group.ISearch.Name(StringField.Condition.NotEquals, groupName),
                        Group.ISearch.Enabled(BooleanField.Condition.Equals, true),
                        Group.ISearch.IsDeleted(BooleanField.Condition.Equals, false));
                    allGroups = new Collection<Group>(Group.Search(searchQuery, connection));
                }
                catch (RecordNotFoundException)
                {
                    allGroups = new Collection<Group>();
                }

                return allGroups;
            }


            /// <summary>
            /// Fetches all active Group for the Passed group credential  
            /// </summary>
            /// <param name="groupName">GroupNames</param>
            /// <param name="connection">Registry connectionection.</param>
            /// <returns>Group of the passed credential .</returns>
            public static Group GetGroupCredential(string groupName, Connection connection)
            {
                #region Validation of Arguments

                if (null == connection)
                {
                    throw new ArgumentNullException("connection");
                }

                #endregion

                List<GroupCredential> allGroupCredential = null;
                try
                {
                    allGroupCredential = GroupCredential.LoadAll(connection);
                    GroupCredential groupCredential = allGroupCredential.FirstOrDefault(p => p.Credential.ToLower().Equals(groupName.ToLower()) &&
                        p.Group.Enabled == true && p.Group.IsDeleted == false);
                    if (groupCredential != null)
                    {
                        return groupCredential.Group;
                    }
                }
                catch (RecordNotFoundException)
                {
                }

                return null;
            }

            /// <summary>
            /// Fetches all enabled Groups .
            /// </summary>
            /// <param name="connection">Registry connectionection.</param>
            /// <returns>Collection of enabled groups.</returns>
            public static Collection<Group> GetAllEnabledGroups(Connection connection)
            {
                #region Validation of Arguments
                if (null == connection)
                {
                    throw new ArgumentNullException("connection");
                }
                #endregion
                Collection<Group> enabledUsers = new Collection<Group>();
                try
                {
                    Group.ISearch searchQuery = Group.ISearch.Create();
                    searchQuery.Query = Group.ISearch.AND(
                    Group.ISearch.IsDeleted(BooleanField.Condition.Equals, false),
                    Group.ISearch.Enabled(BooleanField.Condition.Equals, true));
                    enabledUsers = new Collection<Group>(Group.Search(searchQuery, connection));
                }
                catch (RecordNotFoundException)
                {
                    enabledUsers = new Collection<Group>();
                }
                return enabledUsers;
            }

        }
        #endregion
    }
}
